package com.gooluke.spring;

import com.gooluke.spring.annotation.Autowired;
import com.gooluke.spring.annotation.Component;
import com.gooluke.spring.annotation.PostConstruct;
import com.gooluke.spring.annotation.Value;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author gooluke
 * description
 * datetime 2025-04-07 23:08
 */
public class BeanDefinition {

    private String beanName;
    private Constructor<?> constructor;
    private Method postConstructMethod;
    private List<Field> autowiredFields;
    private List<Field> valueFields;
    private Class<?> beanType;

    public BeanDefinition(Class<?> beanType) {
        this.beanType = beanType;
        Component component = beanType.getAnnotation(Component.class);
        this.beanName = component.name().isEmpty() ? toLowerCaseFirstLetter(beanType.getSimpleName()) : component.name();
        this.constructor = beanType.getConstructors()[0];
        this.postConstructMethod = Arrays.stream(beanType.getMethods()).filter(m -> m.isAnnotationPresent(PostConstruct.class)).findAny().orElse(null);
        this.autowiredFields = Arrays.stream(beanType.getDeclaredFields()).filter(f -> f.isAnnotationPresent(Autowired.class)).collect(Collectors.toList());
        this.valueFields = Arrays.stream(beanType.getDeclaredFields()).filter(f -> f.isAnnotationPresent(Value.class)).collect(Collectors.toList());
    }

    private String toLowerCaseFirstLetter(String name) {
        if (name == null || name.isEmpty()) {
            return name;
        }
        return Character.toLowerCase(name.charAt(0)) + name.substring(1);
    }

    public String getName() {
        return this.beanName;
    }

    public Constructor<?> getConstructor() {
        return this.constructor;
    }

    public Method getPostConstructMethod() {
        return this.postConstructMethod;
    }

    public List<Field> getAutowiredFields() {
        return autowiredFields;
    }

    public List<Field> getValueFields() {
        return valueFields;
    }

    public Class<?> getBeanType() {
        return beanType;
    }
}
